/***************************************************************************************

***************************************************************************************/



/*
*************************************************************************************
* File name: rdopt_coding_state.c
* Function:  
Storing/restoring coding state for
Rate-Distortion optimized mode decision
*
*************************************************************************************
*/


#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include "AEC.h"       
#include "rdopt_coding_state.h"

/*
*************************************************************************
* Function:delete structure for storing coding state
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void delete_coding_state (CSptr cs)
{
	if (cs != NULL)
	{
		if (cs->bitstream != NULL)
			free (cs->bitstream);

		//=== coding state structure ===
		free (cs);
		cs=NULL;
	}
}
//#endif

/*
*************************************************************************
* Function:create structure for storing coding state
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

CSptr create_coding_state ()
{
	CSptr cs;

	//=== coding state structure ===
	if ((cs = (CSptr)calloc(1, sizeof(CSobj))) == NULL)
		no_mem_exit("init_coding_state: cs");

	//=== important variables of data partition array ===

	if ((cs->bitstream = (Bitstream*)calloc(1, sizeof(Bitstream))) == NULL)
		no_mem_exit("init_coding_state: cs->bitstream");
	//=== important variables of data partition array ===
	cs->no_part = 1;

	if ((cs->encenv = (EncodingEnvironment*)calloc(cs->no_part, sizeof(EncodingEnvironment))) == NULL)
		no_mem_exit("init_coding_state: cs->encenv");

	cs->mot_ctx = create_contexts_MotionInfo();
	cs->tex_ctx = create_contexts_TextureInfo();

	return cs;
}

/*
*************************************************************************
* Function:store coding state (for rd-optimized mode decision)
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void store_coding_state (CSptr cs)
{
	int					i;
	Bitstream            *bs_src, *bs_dest;
	Macroblock           *currMB = &(img->mb_data[img->current_mb_nr]);
	EncodingEnvironment  *ee_src, *ee_dest;
	MotionInfoContexts   *mc_src;//  = img->currentSlice->mot_ctx;
	TextureInfoContexts  *tc_src;//  = img->currentSlice->tex_ctx;
	MotionInfoContexts   *mc_dest;// = cs->mot_ctx;
	TextureInfoContexts  *tc_dest;//= cs->tex_ctx;
	mc_src = img->currentSlice->mot_ctx;
	tc_src = img->currentSlice->tex_ctx;
	mc_dest = cs->mot_ctx;
	tc_dest = cs->tex_ctx;

	if (!input->rdopt)
		return;

	for (i = 0; i < 1; i++)
	{
		bs_src = currBitStream;
		bs_dest = cs->bitstream;

		ee_src = &(img->currentSlice->partArr[i].ee_AEC);
		ee_dest = &(cs->encenv[i]);

		memcpy(ee_dest, ee_src, sizeof(EncodingEnvironment));
		memcpy(bs_dest, bs_src, sizeof(Bitstream));
	}

	memcpy(mc_dest, mc_src, sizeof(MotionInfoContexts));
	memcpy(tc_dest, tc_src, sizeof(TextureInfoContexts));

	//=== syntax element number and bitcounters ===
	cs->currSEnr = currMB->currSEnr;
	memcpy(cs->bitcounter, currMB->bitcounter, MAX_BITCOUNTER_MB*sizeof(int));

	//=== elements of current macroblock ===
	memcpy(cs->mvd, currMB->mvd, 2 * 2 * BLOCK_MULTIPLE*BLOCK_MULTIPLE*sizeof(int));
	cs->cbp_bits = currMB->cbp_bits;

}

/*
*************************************************************************
* Function:restore coding state (for rd-optimized mode decision)
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void reset_coding_state (CSptr cs)
{
	int  i;

	EncodingEnvironment  *ee_src, *ee_dest;
	Bitstream            *bs_src, *bs_dest;

	MotionInfoContexts   *mc_dest;// = img->currentSlice->mot_ctx;
	TextureInfoContexts  *tc_dest;//= img->currentSlice->tex_ctx;
	MotionInfoContexts   *mc_src;//= cs->mot_ctx;
	TextureInfoContexts  *tc_src;//= cs->tex_ctx;
	Macroblock           *currMB = &(img->mb_data[img->current_mb_nr]);

	mc_dest = img->currentSlice->mot_ctx;
	tc_dest = img->currentSlice->tex_ctx;
	mc_src = cs->mot_ctx;
	tc_src = cs->tex_ctx;

	if (!input->rdopt)  return;


	//=== important variables of data partition array ===
	//only one partition for IDR img
	//  for (i = 0; i <(img->currentPicture->idr_flag? 1:cs->no_part); i++)
	for (i = 0; i < 1; i++)
	{
		ee_dest = &(img->currentSlice->partArr[i].ee_AEC);
		ee_src = &(cs->encenv[i]);
		bs_dest = currBitStream;

		bs_src = &(cs->bitstream[i]);

		//--- parameters of encoding environments ---
		memcpy(ee_dest, ee_src, sizeof(EncodingEnvironment));
		memcpy(bs_dest, bs_src, sizeof(Bitstream));
	}


	//=== contexts for binary arithmetic coding ===
	memcpy(mc_dest, mc_src, sizeof(MotionInfoContexts));
	memcpy(tc_dest, tc_src, sizeof(TextureInfoContexts));


	//=== syntax element number and bitcounters ===
	currMB->currSEnr = cs->currSEnr;
	memcpy(currMB->bitcounter, cs->bitcounter, MAX_BITCOUNTER_MB*sizeof(int));

	//=== elements of current macroblock ===
	memcpy(currMB->mvd, cs->mvd, 2 * 2 * BLOCK_MULTIPLE*BLOCK_MULTIPLE*sizeof(int));
	currMB->cbp_bits = cs->cbp_bits;

}

